/*
 * Copyright (c) 2010 by Aleksey Zhukov
 * Licensed under the Apache License, Version 2.0 (the "License")
 */

package ru.listfunc4j;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;

/**
 * User: J0k3r
 * Date: 20.11.2010
 * Time: 21:37:54
 */
public class LibraryWork {
    protected static File unpackFromRes(String name, InputStream in) throws IOException {
        if (in == null) return null;
        File file = new File(name);
        if (!file.exists()) {
            file.createNewFile();
            file.deleteOnExit();
            FileOutputStream out = new FileOutputStream(file);
            byte[] buffer = new byte[1048];
            while(in.available() > 0) {
                int read = in.read(buffer);
                out.write(buffer, 0, read);
            }
            out.close();
        }
        return file;
    }

    public static void addDir2LibraryPath(String s) throws IOException {
		try {
			// This enables the java.library.path to be modified at runtime
			// From a Sun engineer at http://forums.sun.com/thread.jspa?threadID=707176
			Field field = ClassLoader.class.getDeclaredField("usr_paths");
			field.setAccessible(true);
			String[] paths = (String[])field.get(null);
            for (String path : paths) if (s.equals(path)) return;
			String[] tmp = new String[paths.length+1];
			System.arraycopy(paths,0,tmp,0,paths.length);
			tmp[paths.length] = s;
			field.set(null,tmp);
			System.setProperty("java.library.path", System.getProperty("java.library.path") + File.pathSeparator + s);
		} catch (IllegalAccessException e) {
			throw new IOException("Failed to get permissions to set library path");
		} catch (NoSuchFieldException e) {
			throw new IOException("Failed to get field handle to set library path");
		}
	}

    public static void initilizeLibrary() throws IOException {
        // adding project root as directory for libraries
        LibraryWork.addDir2LibraryPath(".");
        // unpacking libraries
        // unfortunately, we can't use System.load() becouse Agent logics uses System.loadLibrary inside
        String libFileName = System.mapLibraryName("attach");
        LibraryWork.unpackFromRes(libFileName, ClassLoader.getSystemClassLoader().getResourceAsStream(libFileName));
    }

    public static void main(String[] args) {
        System.out.println("Required library: " + System.mapLibraryName("attach"));
    }
}
